from typing import Dict, List, Any
import re

def to_pascal_case(s: str) -> str:
    """转换为帕斯卡命名法 (PascalCase)"""
    # 先转换为小写并替换特殊字符为空格
    s = re.sub(r'[^a-zA-Z0-9]', ' ', s.lower())
    # 将每个单词首字母大写并移除空格
    return ''.join(word.capitalize() for word in s.split())

def to_camel_case(s: str) -> str:
    """转换为驼峰命名法 (camelCase)"""
    pascal = to_pascal_case(s)
    return pascal[0].lower() + pascal[1:] if pascal else ''

def to_snake_case(s: str) -> str:
    """转换为下划线命名法 (snake_case)"""
    # 先转换为小写并替换特殊字符为下划线
    s = re.sub(r'[^a-zA-Z0-9]', '_', s.lower())
    # 移除多余的下划线
    return re.sub(r'_+', '_', s).strip('_')

def to_upper_snake_case(s: str) -> str:
    """转换为大写下划线命名法 (UPPER_SNAKE_CASE)"""
    return to_snake_case(s).upper()

def to_kebab_case(s: str) -> str:
    """转换为中划线命名法 (kebab-case)"""
    return to_snake_case(s).replace('_', '-')

def to_constant_case(s: str) -> str:
    """转换为常量命名法 (CONSTANT_CASE)"""
    return to_upper_snake_case(s)

def to_package_path(s: str) -> str:
    """转换为包路径 (package.path)"""
    return to_snake_case(s)

def to_flat_lowercase(s: str) -> str:
    return s.replace('_', '').lower()

def generate_table_naming(business_name: str) -> Dict[str, str]:
    """生成表级命名"""
    pascal_name = to_pascal_case(business_name)
    return {
        "class_name": pascal_name,
        "detail_component_name": f"{pascal_name}Detail",
        "list_component_name": f"{pascal_name}ListPage",
        "controller_name": f"{pascal_name}Controller",
        "service_name": f"{pascal_name}Service",
        "service_impl_name": f"{pascal_name}ServiceImpl",
        "mapper_name": f"{pascal_name}Mapper",
        "mapper_xml_name": f"{pascal_name}Mapper.xml",
        "repository_name": f"{pascal_name}Repository",
        "dao_name": f"{pascal_name}Dao",
        "dto_name": f"{pascal_name}DTO",
        "vo_name": f"{pascal_name}VO",
        "query_dto_name": f"{pascal_name}QueryDTO",
        "result_vo_name": f"{pascal_name}ResultVO",
        "page_query_dto_name": f"{pascal_name}PageQueryDTO",
        "page_result_vo_name": f"{pascal_name}PageResultVO",
        "create_dto_name": f"Create{pascal_name}DTO",
        "update_dto_name": f"Update{pascal_name}DTO",
        "PascalName": pascal_name,
        "camelName": to_camel_case(business_name),
        "snake_name": to_snake_case(business_name),
        "UPPER_SNAKE_NAME": to_upper_snake_case(business_name),
        "kebab-name": to_kebab_case(business_name),
        "CONSTANT_NAME": to_constant_case(business_name),
        "package_path": to_package_path(business_name),
        "flat_lowercase": to_flat_lowercase(business_name)
    }

def generate_column_naming(column_name: str) -> Dict[str, str]:
    """生成字段级命名"""
    pascal_name = to_pascal_case(column_name)
    camel_name = to_camel_case(column_name)
    return {
        "field_name": camel_name,
        "FieldName": pascal_name,
        "snake_name": to_snake_case(column_name),
        "UPPER_SNAKE_NAME": to_upper_snake_case(column_name),
        "kebab-name": to_kebab_case(column_name),
        "CONSTANT_NAME": to_constant_case(column_name),
        "getter_name": f"get{pascal_name}",
        "setter_name": f"set{pascal_name}"
    }

def generate_naming(meta: Dict[str, Any]) -> Dict[str, Any]:
    """根据meta.json生成完整的naming结构

    :param meta: meta.json格式的结构体
    :return: 更新后的结构体,可以继续传递给其他处理函数
    """
    business_name = meta["table"]["mark"]["business_name"]

    # 生成表级命名 - 放到table.derived.naming中
    if "derived" not in meta["table"]:
        meta["table"]["derived"] = {}
    if "naming" not in meta["table"]["derived"]:
        meta["table"]["derived"]["naming"] = {}
    meta["table"]["derived"]["naming"].update(generate_table_naming(business_name))

    # 生成字段级命名
    if isinstance(meta.get("columns"), dict):
        # 处理对象形式的columns
        for name, column in meta["columns"].items():
            if "naming" not in column:
                column["naming"] = {}
            column["naming"].update(generate_column_naming(name))
    else:
        # 处理数组形式的columns
        for column in meta.get("columns", []):
            column_name = column["sql"]["name"]
            if "naming" not in column:
                column["naming"] = {}
            column["naming"].update(generate_column_naming(column_name))

    return meta